package dbUtils

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"gitee.com/lv_baobao/gcore"
	"gitee.com/lv_baobao/gcore/logHelper"
	"io/ioutil"
	"net"
	"os"
	"sync"
)

type SendHead struct {
	SendType   uint32
	ContentLen uint32
}

type SendPacket struct {
	Head    SendHead
	Content interface{}
}

type DbLogSender struct {
	MaxIndex int
	conn     net.Conn
	lock     sync.Mutex
}

var dbLogSenderOnce sync.Once
var dbLogSender *DbLogSender

func NewDbLogSender() *DbLogSender {
	dbLogSenderOnce.Do(func() {
		dbLogSender = &DbLogSender{}
		dbLogSender.MaxIndex = 655350000
	})
	return dbLogSender
}

func (d *DbLogSender) GetOldFirstFilePath() (string, error) {
	files, err := ioutil.ReadDir("dblog/senderLogs")
	if err != nil {
		return "", err
	}
	if len(files) == 0 {
		return "", nil
	}

	var tempFile = files[0]
	for _, file := range files {
		if file.ModTime().Before(tempFile.ModTime()) {
			tempFile = file
		}
	}
	filePath := fmt.Sprintf("dblog/senderLogs/%s", tempFile.Name())
	return filePath, nil
}

func (d *DbLogSender) StartSendFile() {
	path, err := d.GetOldFirstFilePath()
	if err != nil {
		logHelper.Error(err)
		return
	}
	if path == "" {
		return
	}

	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		logHelper.Error(err)
		return
	}
	err = d.Send(bytes)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = os.Remove(path)
	if err != nil {
		logHelper.Error("remove file err", err)
	}
}

func (d *DbLogSender) Send(bytes []byte) error {
	if d.conn == nil {
		d.lock.Lock()
		defer d.lock.Unlock()
		address := gcore.NewAppSettingsHelper().GetAppConfig().DbSyncServerAddress
		if address == "" {
			return errors.New("DbSyncServerAddress is null")
		}
		conn, err := net.Dial("tcp", address)
		if err != nil {
			return err
		}
		d.conn = conn
	}
	head := SendHead{
		SendType:   0,
		ContentLen: uint32(len(bytes)),
	}
	headBytes, err := d.GetHeaderBytes(head)
	if err != nil {
		return err
	}
	_, err = d.conn.Write(headBytes)
	if err != nil {
		d.conn.Close()
		d.conn = nil
		return err
	}
	_, err = d.conn.Write(bytes)
	if err != nil {
		d.conn.Close()
		d.conn = nil
		return err
	}
	fmt.Println("send file bytes success")
	return nil
}

func (d *DbLogSender) GetHeaderBytes(head SendHead) ([]byte, error) {
	var buf bytes.Buffer

	err := binary.Write(&buf, binary.BigEndian, uint32(head.SendType))
	if err != nil {
		return nil, err
	}
	err = binary.Write(&buf, binary.BigEndian, uint32(head.ContentLen))
	return buf.Bytes(), err
}

//func (d *DbLogSender) SendN(bytes []byte,) error{
//	fmt.Println("send file bytes success")
//
//	conn, err := net.Dial("tcp", ":7777")
//	if err != nil {
//		logHelper.Error(err)
//		return err
//	}
//	conn.Write()
//	return nil
//}
